home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1999 November / Macworld (1999-11).dmg / Updaters / WhiteCap 3.0.4 / WhiteCap Source.sit / WhiteCap Source / mainWinamp.cpp < prev    next >
Text File  |  1999-08-29  |  11KB  |  466 lines

  1. // Winamp test visualization library v1.0
  2.  
  3.  
  4. #include <windows.h>
  5.  
  6. #include "WhiteCap.h"
  7. #include "EgOSUtils.h"
  8. #include "RectUtils.h"
  9. #include "CEgFileSpec.h"
  10.  
  11. #include "vis.h"
  12.  
  13.  
  14. char szAppName[] = "WhiteCap"; // Our window class, etc
  15.  
  16.  
  17. // returns a winampVisModule when requested. Used in hdr, below
  18. winampVisModule *getModule(int which);
  19.  
  20. // "member" functions
  21. void config(struct winampVisModule *this_mod); // configuration dialog
  22. int init(struct winampVisModule *this_mod);       // initialization for module
  23. int Go(struct winampVisModule *this_mod);  // rendering for module 1
  24. void quit(struct winampVisModule *this_mod);   // deinitialization for module
  25.  
  26. // our window procedure
  27. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
  28. HWND hMainWnd; // main window handle
  29.  
  30.  
  31.  
  32. // Module header, includes version, description, and address of the module retriever function
  33. winampVisHeader hdr = { VIS_HDRVER, "WhiteCap", getModule };
  34.  
  35.  
  36.  
  37. class WhiteCap;
  38.  
  39. static WhiteCap*        gWC = NULL;
  40. static float            gSample[ NUM_SAMPLE_BINS ];
  41.  
  42.  
  43.  
  44. winampVisModule gWCModule =
  45. {
  46.     "WhiteCap",
  47.     NULL,    // hwndParent
  48.     NULL,    // hDllInstance
  49.     0,        // sRate
  50.     0,        // nCh
  51.     25,        // latencyMS
  52.     25,        // delayMS
  53.     2,        // spectrumNch
  54.     0,        // waveformNch
  55.     { 0, },    // spectrumData
  56.     { 0, },    // waveformData
  57.     config,
  58.     init,
  59.     Go, 
  60.     quit
  61. };
  62.  
  63.  
  64.  
  65.  
  66.  
  67. // this is the only exported symbol. returns our main header.
  68. // if you are compiling C++, the extern "C" { is necessary, so we just #ifdef it
  69. #ifdef __cplusplus
  70. extern "C" {
  71. #endif
  72. __declspec( dllexport ) winampVisHeader *winampVisGetHeader()
  73. {
  74.     return &hdr;
  75. }
  76. #ifdef __cplusplus
  77. }
  78. #endif
  79.  
  80. // getmodule routine from the main header. Returns NULL if an invalid module was requested,
  81. // otherwise returns either mod1, mod2 or mod3 depending on 'which'.
  82. winampVisModule *getModule(int inWhich )
  83. {
  84.  
  85.         
  86.     if ( inWhich == 0 )    
  87.         return &gWCModule;
  88.     else
  89.         return NULL;
  90. }
  91.  
  92. // configuration. Passed this_mod, as a "this" parameter. Allows you to make one configuration
  93. // function that shares code for all your modules (you don't HAVE to use it though, you can make
  94. // config1(), config2(), etc...)
  95. void config(struct winampVisModule *this_mod)
  96. {
  97.     MessageBox(this_mod->hwndParent,"Right click on the WhiteCap window to change configs.\n"
  98.                                     "Be sure to read the readme file!\n", "", MB_OK);
  99. }
  100.  
  101. // initialization. Registers our window class, creates our window, etc. Again, this one works for
  102. // both modules, but you could make init1() and init2()...
  103. // returns 0 on success, 1 on failure.
  104. int init(struct winampVisModule *this_mod)
  105. {
  106.  
  107.     EgOSUtils::Initialize();
  108.     PixPort::Startup();
  109.  
  110.     
  111.     {    // Register our window class
  112.         WNDCLASS wc;
  113.         memset(&wc,0,sizeof(wc));
  114.         wc.lpfnWndProc = WndProc;                // our window procedure
  115.         wc.hInstance = this_mod->hDllInstance;    // hInstance of DLL
  116.         wc.lpszClassName = szAppName;            // our window class name
  117.         wc.hCursor = ::LoadCursor( NULL, IDC_ARROW );
  118.         //wc.hbrBackground = ::GetSysColorBrush( COLOR_BACKGROUND + 1 );
  119.         wc.style = CS_BYTEALIGNCLIENT;
  120.         
  121.         ::RegisterClass(&wc);
  122.     }
  123.  
  124.     // Make A WhiteCap!
  125.     CEgFileSpec folder;
  126.     folder.AssignFolder( "Plugins\\WhiteCap Configs\\" );
  127.     gWC = new WhiteCap( folder );    
  128.  
  129.     hMainWnd = CreateWindowEx(
  130.         WS_EX_TOOLWINDOW,                    // these exstyles put a nice small frame, 
  131.                                             // but also a button in the taskbar
  132.         szAppName,                            // our window class name
  133.         this_mod->description,                // use description for a window title
  134.         WS_SYSMENU | WS_THICKFRAME,            // make the window visible with a close button
  135.         0,0,                                // screen position (read from config)
  136.         200,200,                            // width & height of window (need to adjust client area later)
  137.         this_mod->hwndParent,                // parent window (winamp main window)
  138.         NULL,                                // no menu
  139.         this_mod->hDllInstance,                // hInstance of DLL
  140.         0); // no window creation data
  141.  
  142.  
  143.     SetWindowLong(hMainWnd,GWL_USERDATA,(LONG)this_mod); // set our user data to a "this" pointer
  144.  
  145.  
  146.     gWC -> SetWinPort( hMainWnd );
  147.     ::ShowWindow( hMainWnd, SW_SHOWNORMAL );
  148.  
  149.     return 0;
  150. }
  151.  
  152.  
  153.  
  154. #define _ABS( x ) (( (x) > 0 ) ? (x) : (-x))
  155. int Go(struct winampVisModule *this_mod)
  156. {
  157.     long sum, idx;
  158.  
  159. /*
  160.     idx = 8;
  161.     for ( int i = 0; i < NUM_SAMPLE_BINS; i++ ) {
  162.         sum = 0;
  163.         for ( int j = 0; j < i+3; j++, idx++ ) 
  164.             sum += ((unsigned) this_mod->spectrumData[0][idx] );
  165.         gSample[ i ] = sum;
  166.     }
  167.     
  168.     idx = 8;
  169.     for ( int i = 0; i < NUM_SAMPLE_BINS; i++ ) {
  170.         sum = 0;
  171.         for ( int j = 0; j < i+3; j++, idx++ ) 
  172.             sum += ((unsigned) this_mod->spectrumData[1][idx] );
  173.         gSample[ i ] = ((float) sum + gSample[ i ]) / (350.0);
  174.     }*/
  175.  
  176.     int i, j;
  177.     
  178.     /*
  179.     idx = 4;
  180.     for ( sum = 0, j = 0; j < 2; j++, idx++ ) {
  181.         sum += ((unsigned long) this_mod->spectrumData[0][idx]) + ((unsigned long) this_mod->spectrumData[1][idx]);
  182.     }
  183.     gSample[ 0 ] = sum / 400;
  184.     
  185.     for ( sum = 0, j = 0; j < 3; j++, idx++ ) {
  186.         sum += ((unsigned long) this_mod->spectrumData[0][idx]) + ((unsigned long) this_mod->spectrumData[1][idx]);
  187.     }
  188.     gSample[ 1 ] = sum / 400;
  189.  
  190.     for ( sum = 0, j = 0; j < 4; j++, idx++ ) {
  191.         sum += ((unsigned long) this_mod->spectrumData[0][idx]) + ((unsigned long) this_mod->spectrumData[1][idx]);
  192.     }
  193.     gSample[ 2 ] = sum / 400;
  194.  
  195.  
  196.     for ( sum = 0, j = 0; j < 5; j++, idx++ ) {
  197.         sum += ((unsigned long) this_mod->spectrumData[0][idx]) + ((unsigned long) this_mod->spectrumData[1][idx]);
  198.     }
  199.     gSample[ 4 ] = sum / 400;*/
  200.     
  201.  
  202.     float factor, binVal;
  203.     float scale = .85 * UNIV_MAG_SCALE;
  204.     
  205.     idx = 15;
  206.     for ( i = 0; i < NUM_SAMPLE_BINS; i++ ) {
  207.         sum = 0;
  208.         for ( j = 0; j < 8; j++, idx++ ) 
  209.             sum +=  ((unsigned) this_mod->spectrumData[0][idx]);
  210.         gSample[ i ] = sum;
  211.     }
  212.     
  213.     idx = 15;
  214.     for ( i = 0; i < NUM_SAMPLE_BINS; i++ ) {
  215.         sum = 0;
  216.         for ( j = 0; j < 8; j++, idx++ ) 
  217.             sum += ((unsigned) this_mod->spectrumData[1][idx]);
  218.         binVal = ((float) sum + gSample[ i ]) * (0.81 + (float) i / 24);
  219.         
  220.         /*
  221.         factor = .4 + .27 / ( 1.50 * binVal + .4 );
  222.         if ( factor < 1 )
  223.             binVal *= factor;
  224.         gSample[ i ] = .6 * binVal;*/
  225.  
  226.  
  227.         gSample[ i ] = scale * ( log( .00401785 * binVal + 1 ) );  // = .85 * ( log( .006429 * binVal + 1.6 ) - log( 1.6 ) );
  228.     }
  229.     
  230.     gSample[ 0 ] *= 0.45;
  231.     gSample[ 1 ] *= 0.65;
  232.  
  233.     long time = ::timeGetTime();
  234.     gWC -> RecordSample( time, gSample );
  235.     gWC -> Draw();
  236.  
  237.     return 0;
  238.  
  239. }
  240.  
  241. /*
  242.             sum += ((unsigned) this_mod->spectrumData[1][idx]);
  243.         binVal = ((float) sum + gSample[ i ]) * (0.81 + (float) i / 17) / ( 140 );
  244.  
  245.         gSample[ i ] = 1.5 * ( log( .008 * binVal + 1.4 ) - log( 1.4 ) );
  246. */
  247.  
  248. // cleanup (opposite of init()). Destroys the window, unregisters the window class
  249. void quit(struct winampVisModule *this_mod)
  250. {
  251.  
  252.     if ( gWC ) {/*
  253.         RECT wr;
  254.         ::GetClientRect( hMainWnd, &wr );
  255.         UtilStr str;
  256.         str.Append( wr.top );
  257.         str.Append( "  " );
  258.                 str.Append( wr.left );
  259.         str.Append( "  " );
  260.                 str.Append( wr.bottom );
  261.         str.Append( "  " );
  262.                 str.Append( wr.right );
  263.         str.Append( "  " );
  264.         EgOSUtils::ShowMsg( str );*/
  265.         delete gWC;
  266.         gWC = NULL;
  267.     }
  268.     
  269.     
  270.     PixPort::Shutdown();
  271.  
  272.     
  273.     ::DestroyWindow(hMainWnd); // delete our window
  274.     ::UnregisterClass(szAppName,this_mod->hDllInstance); // unregister window class
  275. }
  276.  
  277.  
  278.  
  279.  
  280. /*
  281.  
  282. // render function for oscilliscope. Returns 0 if successful, 1 if visualization should end.
  283. int render1(struct winampVisModule *this_mod)
  284. {
  285.     int x, y;
  286.     // clear background
  287.     Rectangle(memDC,0,0,288,256);
  288.     // draw oscilliscope
  289.     for (y = 0; y < this_mod->nCh; y ++)
  290.     {
  291.         MoveToEx(memDC,0,(y*256)>>(this_mod->nCh-1),NULL);
  292.         for (x = 0; x < 288; x ++)
  293.         {
  294.             LineTo(memDC,x,(y*256 + this_mod->waveformData[y][x]^128)>>(this_mod->nCh-1));
  295.         }
  296.     }
  297.     { // copy doublebuffer to window
  298.         HDC hdc = GetDC(hMainWnd);
  299.         BitBlt(hdc,0,0,288,256,memDC,0,0,SRCCOPY);
  300.         ReleaseDC(hMainWnd,hdc);
  301.     }
  302.     return 0;
  303. }
  304.  
  305. // render function for analyser. Returns 0 if successful, 1 if visualization should end.
  306. int render2(struct winampVisModule *this_mod)
  307. {
  308.     int x, y;
  309.     // clear background
  310.     Rectangle(memDC,0,0,288,256);
  311.     // draw analyser
  312.     for (y = 0; y < this_mod->nCh; y ++)
  313.     {
  314.         for (x = 0; x < 288; x ++)
  315.         {
  316.             MoveToEx(memDC,x,(y*256+256)>>(this_mod->nCh-1),NULL);
  317.             LineTo(memDC,x,(y*256 + 256 - this_mod->spectrumData[y][x])>>(this_mod->nCh-1));
  318.         }
  319.     }
  320.     { // copy doublebuffer to window
  321.         HDC hdc = GetDC(hMainWnd);
  322.         BitBlt(hdc,0,0,288,256,memDC,0,0,SRCCOPY);
  323.         ReleaseDC(hMainWnd,hdc);
  324.     }
  325.     return 0;
  326. }
  327.  
  328. // render function for VU meter. Returns 0 if successful, 1 if visualization should end.
  329. int render3(struct winampVisModule *this_mod)
  330. {
  331.     int x, y;
  332.     // clear background
  333.     Rectangle(memDC,0,0,256,32);
  334.     // draw VU meter
  335.     for (y = 0; y < 2; y ++)
  336.     {
  337.         int last=this_mod->waveformData[y][0];
  338.         int total=0;
  339.         for (x = 1; x < 576; x ++)
  340.         {
  341.             total += abs(last - this_mod->waveformData[y][x]);
  342.             last = this_mod->waveformData[y][x];
  343.         }
  344.         total /= 288;
  345.         if (total > 127) total = 127;
  346.         if (y) Rectangle(memDC,128,0,128+total,32);
  347.         else Rectangle(memDC,128-total,0,128,32);
  348.     }
  349.     { // copy doublebuffer to window
  350.         HDC hdc = GetDC(hMainWnd);
  351.         BitBlt(hdc,0,0,256,32,memDC,0,0,SRCCOPY);
  352.         ReleaseDC(hMainWnd,hdc);
  353.     }
  354.     return 0;
  355. }
  356.  
  357. */
  358.  
  359.  
  360.  
  361.  
  362.  
  363.  
  364.                                 
  365. int WINAPI WinMain( HINSTANCE hInst,     /*Win32 entry-point routine */
  366.                     HINSTANCE hPreInst, 
  367.                     LPSTR lpszCmdLine, 
  368.                     int nCmdShow )
  369. {
  370.     MSG lpMsg;
  371.  
  372.     init( &gWCModule );
  373.  
  374.     while( GetMessage( &lpMsg, NULL, 0, 0 ) )                    /* begin the message loop */
  375.     {
  376.         Go( &gWCModule );
  377.         TranslateMessage( &lpMsg );
  378.         DispatchMessage( &lpMsg );
  379.     }
  380.     return( lpMsg.wParam);
  381. }
  382.  
  383.  
  384.  
  385.  
  386.  
  387. // window procedure for our window
  388. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  389. {
  390.     static long sLastClickTime = 0;
  391.     
  392.     switch ( message )
  393.     {
  394.  
  395.             /*
  396.         case WM_NCLMOUSEMOVE:
  397.         case WM_MOUSEMOVED:
  398.             if ( gWC -> IsAtFullScreen() )
  399.                 return 0;
  400.             break;
  401.             
  402.         case WM_NCRBUTTONDOWN:
  403.             if ( ! gWC -> IsAtFullScreen() )
  404.                 break;*/
  405.         case WM_RBUTTONDOWN:
  406.             if ( (wParam & MK_RBUTTON) && gWC )
  407.                 gWC -> SelectConfig();
  408.             return 0;            
  409.             break;
  410.         
  411.         //case WM_NCLBUTTONDOWN:
  412.         case WM_LBUTTONDOWN:
  413.             if ( gWC -> IsFullScreen() )
  414.                 gWC -> SetFullScreen( false );
  415.             else if ( message == WM_LBUTTONDOWN ) {
  416.                 long curTime = EgOSUtils::CurTimeMS();
  417.                 if ( curTime - 300 < sLastClickTime )
  418.                     gWC -> SetFullScreen( true );
  419.                 else
  420.                     sLastClickTime = curTime;
  421.             }
  422.             return 0;    
  423.             break;
  424.     
  425.         case WM_CREATE:        return 0;
  426.         case WM_ERASEBKGND:    return 0;
  427.         case WM_PAINT:
  428.             { // update from doublebuffer
  429.                 PAINTSTRUCT ps;
  430.                 HDC hdc = BeginPaint( hwnd, &ps );
  431.                 Rect r;
  432.                 SetRect( &r, ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom );
  433.                 gWC -> RefreshRect( r );
  434.                 gWC -> Draw();
  435.                 EndPaint( hwnd, &ps );
  436.  
  437.             }
  438.             return 0;
  439.         case WM_DESTROY: PostQuitMessage(0); return 0;
  440.         case WM_KEYDOWN: // pass keyboard messages to main winamp window (for processing)
  441.         case WM_KEYUP:
  442.             {    // get this_mod from our window's user data
  443.                 winampVisModule *this_mod = (winampVisModule *) GetWindowLong(hwnd,GWL_USERDATA);
  444.                 PostMessage(this_mod->hwndParent,message,wParam,lParam);
  445.             }
  446.         return 0;
  447.         case WM_MOVE:
  448.             return 0;
  449.         case WM_SIZE:
  450.             {
  451.                 if ( gWC ) {
  452.                     if ( ! gWC -> IsFullScreen() ) {
  453.                     
  454.                         Rect r;
  455.                         gWC -> GetWinRect( r );
  456.                         gWC -> SetWinPort( hwnd, &r );
  457.                     }
  458.                 }
  459.  
  460.             }
  461.             return 0;
  462.     }
  463.     return DefWindowProc(hwnd,message,wParam,lParam);
  464. }
  465.  
  466.